var grid = function(){
	var _self = this, jGrid, jFm, jCells, box = null, curCell = null;
	var defConfig = {
		gridId: '#grid',
		formId: '#data',
		cellExp: 'td.cell'
	};
	var cfg = this.config = {};
	this.init = function(usrConfig){
		usrConfig = usrConfig || {};
		cfg = this.config = $.extend({}, defConfig, usrConfig);
		jFm = $(cfg.formId);
		jGrid = $(cfg.gridId);
		jCells = $(cfg.cellExp, jGrid);
		// make cells editable, which has 'cell' css class
		this.initCells();
		// fill data use form data
		this.fill();
		// init cell common action
		jCells
		.click(function(eve){
			_self.select($(this));
		})
		.keydown(function(eve){
			if($.inArray(eve.keyCode, [9, 13, 39]) != -1){
				_self.select('next');
				return false;
			}else if(eve.keyCode == 37){
				_self.select('prev');
				return false;
			}
		})
		.keyup(function(){_self.sync(this);});
		// init droplist bind with form.select
		jCells.filter('.select')
		.hover(
			function(){$(this).addClass('mover');},
			function(){$(this).removeClass('mover');}
		)
		.click(function(eve){
			eve.stopPropagation();
			_self.appendDropList($(this), jFm[0][this.id])
		});
		// init autocomplete list
		if(jCells.autosuggest){
			jCells.filter('.autocomplete').autosuggest({
				url:'./autosuggest.html',
				onchange: function(val){
					_self.sync(this);
				}
			});
		}
		if($.datepicker){
			$.datepicker.setDefaults($.extend({showMonthAfterYear: false,changeMonth: true,changeYear: true,showButtonPanel: true}, $.datepicker.regional['zh_CN']));
			jCells.filter('.date').datepicker();
		}
	};
	this.initCells = function(){
		jCells.html('<div contentEditable="true"></div>');
	};
	this.fill = function(d){
		var D = $.isArray(d) ? d : jFm.serializeArray()
		$.each(D, function(i, o){
			$('#' + o.name).html('<div contentEditable="true">' + o.value + '</div>');
		});
	};
	this.sync = function(cell){
		var matchCells = jCells;
		if(cell && cell != undefined){
			if(typeof cell == 'string'){
				matchCells = cells.filter(cell);
			}else{
				matchCells = $(cell);
			}
		}
		$.each(matchCells, function(i, o){
			$(jFm[0][o.id]).val($(o).text());
		});
	};
	this.reset = function(){
		jFm[0].reset();
		this.initCells();
		this.fill();
	};
	this.select = function(jCell){
		var inx = 0;
		if(!jCell || jCell == undefined){
			jCell = jCells.eq(0);
		}else if(jCell == 'prev'){
			jCell = jCells.eq(jCells.index(curCell) - 1);
		}else if(jCell == 'next'){
			jCell = jCells.eq(jCells.index(curCell) + 1);
		}
		inx = jCells.index(jCell);
		if(inx == -1) return inx;
		curCell = jCell;
		_self.focus();
		return inx;
	};
	this.focus = function(){
		if(!curCell) return;
		curCell.find('div').eq(0).focus();
	};
	
	this.appendDropList = function(jCell, el){
		var optns = [], css = '';
		var hide = function(){
			box.remove();
			box = null;
		};
		
		if(!el || el.tagName.toLowerCase() != 'select') return;
		if(box && box.length > 0){box.toggle(); return;}
		
		$.each(el.options, function(i, optn){
			if(optn.selected){
				optns.push('<li id="opt'+i+'" class="selected">'+optn.text+'</li>');
			}else{
				optns.push('<li id="opt'+i+'">'+optn.text+'</li>');
			}
		});
		
		$('body')
		.append('<ol id="dropList" class="drop-list">'+optns.join('')+'</ol>')
		.click(function(){
			hide();
			$(this).unbind('click', arguments.callee)
		});
		
		box = $('#dropList');
		box.css({
			position: 'absolute',
			width: jCell.outerWidth() + 'px',
			left: jCell.offset().left - 1 + 'px',
			top: jCell.offset().top + jCell.outerHeight() + 'px'
		});
		
		var lis = $('li', box)
		.mouseover(function(){
			lis.removeClass('selected');
			$(this).addClass('selected');
		})
		.click(function(){
			curCell.find('div').eq(0).text($(this).text());
			el.options[this.id.replace(/[^\d]+/, '')].selected = true;
		});
	}
};